interface DrawRectOptions {
  x: number;
  y: number;
  width: number;
  height: number;
  color?: string;
}

interface DrawTextOptions {
  text: string;
  x: number;
  y: number;
  color?: string;
  font?: string;
}

interface DrawImageOptions {
  image: HTMLImageElement;
  x: number;
  y: number;
  width: number;
  height: number;
}

interface SaveAsImageOptions {
  filename: string;
}

interface DrawLineOptions {
  startX: number;
  startY: number;
  endX: number;
  endY: number;
  color?: string;
}

interface DrawCircleOptions {
  x: number;
  y: number;
  radius: number;
  color?: string;
}

class CanvasUtil {
  private canvas: HTMLCanvasElement;
  private ctx: any;

  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas;
    this.ctx = canvas.getContext('2d');
  }

  public setCanvasSize(width: number, height: number): void {
    this.canvas.width = width;
    this.canvas.height = height;
  }

  public drawRect(options: DrawRectOptions): void {
    const { x, y, width, height, color } = options;
    this.ctx.fillStyle = color || '#000';
    this.ctx.fillRect(x, y, width, height);
  }

  public drawText(options: DrawTextOptions): void {
    const { text, x, y, color, font } = options;
    this.ctx.font = font || '14px Arial';
    this.ctx.fillStyle = color || '#000';
    this.ctx.fillText(text, x, y);
  }

  public drawLine(options: DrawLineOptions): void {
    const { startX, startY, endX, endY, color } = options;
    this.ctx.strokeStyle = color || '#000';
    this.ctx.beginPath();
    this.ctx.moveTo(startX, startY);
    this.ctx.lineTo(endX, endY);
    this.ctx.stroke();
  }

  public drawCircle(options: DrawCircleOptions): void {
    const { x, y, radius, color } = options;
    this.ctx.fillStyle = color || '#000';
    this.ctx.beginPath();
    this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
    this.ctx.fill();
  }

  public drawImage(options: DrawImageOptions): void {
    const { image, x, y, width, height } = options;
    this.ctx.drawImage(image, x, y, width, height);
  }

  public clear(): void {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }


  public saveAsImage(options: SaveAsImageOptions): void {
    const { filename } = options;
    const dataURL = this.canvas.toDataURL('image/png');
    const link = document.createElement('a');
    link.download = filename;
    link.href = dataURL;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
}

export default CanvasUtil;
